﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GeometricAlg.Model
{
    public class Line2d
    {
        public Point2d Point1 { get; set; }
        public Point2d Point2 { get; set; }

        public Line2d()
        {
        }

        public Line2d(Point2d point1, Point2d point2)
        {
            Point1 = point1;
            Point2 = point2;
        }

        // 判断一个点是否在直线上  
        public bool ContainsPoint(Point2d point, double tolerance = 1e-5)
        {
            //投影法判断是否在线段上
            if (point.Y == Point1.Y && point.Y == Point2.Y)
            {
                return true;
            }
            if (point.X == Point1.X && point.X == Point2.X)
            {
                return true;
            }
            var t = (point.Y - Point1.Y) / (Point2.Y - Point1.Y);
            var x = t * (Point2.X - Point1.X) + Point1.X;
            if (t < -tolerance || t > 1 + tolerance)
            {
                return false; // 点不在线段的参数范围内  
            }

            if (Math.Abs(x - point.X) < tolerance)
            {
                return true;
            }

            return false;

        }

        public bool ContainsPoint2(Point2d point, double tolerance = 1e-5)
        {
            // 使用向量叉积判断点是否在直线上  
            double crossProduct = (Point2.Y - Point1.Y) * (point.X - Point1.X) -
                                  (Point2.X - Point1.X) * (point.Y - Point1.Y);

            return Math.Abs(crossProduct) < double.Epsilon;
        }

        // 计算直线与另一个直线的交点  
        public Point2d? IntersectWith(Line2d other)
        {
            double denominator = (Point2.Y - Point1.Y) * (other.Point2.X - other.Point1.X) - (Point2.X - Point1.X) * (other.Point2.Y - other.Point1.Y);

            if (Math.Abs(denominator) < double.Epsilon)
            {
                // 直线平行或重合  
                return null;
            }

            double x = ((other.Point2.X - other.Point1.X) * (Point1.Y - other.Point1.Y) - (other.Point2.Y - other.Point1.Y) * (Point1.X - other.Point1.X)) / denominator;
            double y = ((Point2.X - Point1.X) * (Point1.Y - other.Point1.Y) - (Point2.Y - Point1.Y) * (Point1.X - other.Point1.X)) / denominator;

            return new Point2d(x, y);
        }

        // 辅助方法：计算两个点的向量叉乘  
        private static double CrossProduct(Point2d p1, Point2d p2, Point2d p3)
        {
            return (p2.X - p1.X) * (p3.Y - p1.Y) - (p2.Y - p1.Y) * (p3.X - p1.X);
        }

        // 辅助方法：计算两点之间的距离的平方  
        private static double DistanceSquared(Point2d p1, Point2d p2)
        {
            double dx = p2.X - p1.X;
            double dy = p2.Y - p1.Y;
            return dx * dx + dy * dy;
        }

        public static bool AreLinesIntersecting(Line2d line1, Line2d line2)
        {
            // 快速排斥实验  
            double minX1 = Math.Min(line1.Point1.X, line1.Point2.X);
            double maxX1 = Math.Max(line1.Point1.X, line1.Point2.X);
            double minY1 = Math.Min(line1.Point1.Y, line1.Point2.Y);
            double maxY1 = Math.Max(line1.Point1.Y, line1.Point2.Y);

            double minX2 = Math.Min(line2.Point1.X, line2.Point2.X);
            double maxX2 = Math.Max(line2.Point1.X, line2.Point2.X);
            double minY2 = Math.Min(line2.Point1.Y, line2.Point2.Y);
            double maxY2 = Math.Max(line2.Point1.Y, line2.Point2.Y);

            if (maxX1 < minX2 || minX1 > maxX2 || maxY1 < minY2 || minY1 > maxY2)
            {
                // 不相交  
                return false;
            }

            // 跨立实验  
            double cp1 = CrossProduct(line1.Point1, line1.Point2, line2.Point1);
            double cp2 = CrossProduct(line1.Point1, line1.Point2, line2.Point2);
            if (cp1 * cp2 >= 0) return false; // 不跨立  

            double cp3 = CrossProduct(line2.Point1, line2.Point2, line1.Point1);
            double cp4 = CrossProduct(line2.Point1, line2.Point2, line1.Point2);
            if (cp3 * cp4 >= 0) return false; // 不跨立  
            
            
            return true;
        }

        // 其他可能的方法，比如计算到点的距离、旋转、平移等  
    }
}
